본문으로 건너뛰기

23.06.01

오늘 한 일

  • 알고리즘 문제 풀이
  • 바닐라 JS 리액트 스터디 내용 정리 및 참여
  • 카공실록 리뷰 작성 바텀시트 마무리 작업(react-hook-form 고려)
  • 스마트기기시스템 과제 완료
  • 카공실록 회의

카공실록 작성 바텀시트 구현

작업 마무리 해서 PR 올렸다.

Jun-01-2023 21-07-25

Tab 컴포넌트의 재사용 문제

// components/common/Tab.tsx
import { Dispatch, SetStateAction } from 'react';

interface TabProps {
children: React.ReactNode;
id: number;
isSelected: boolean;
setSelectedTab: Dispatch<SetStateAction<number>>;
}

export default function Tab({ children, id, isSelected, setSelectedTab }: TabProps) {
function handleClick() {
setSelectedTab(id);
}

return (
<button
type='button'
className={`${
isSelected
? 'bg-bk100 text-white active:bg-bk80'
: 'border border-bk10 bg-white text-black active:bg-bk10'
} hover:bg- box-border h-8 min-w-fit rounded-full px-[0.9375rem] text-body2 transition-colors`}
onClick={handleClick}
>
{children}
</button>
);
}

Tab 컴포넌트는 탭을 하나만 선택할 수 있는 경우에 사용할 수 있도록 구현되어있다.

메인 페이지에서는 가능하지만, 카페 상세 페이지의 리뷰 등록 바텀시트에서는 탭을 여러개 선택할 수 있어야 한다.

// components/place/Tabs.tsx
import Tab from '@/components/common/Tab';
import { INITIAL_TABS } from '@/constants/place';
import { useEffect, useState } from 'react';

import type { TabType } from '@/types/place';
import type { Dispatch, SetStateAction } from 'react';

interface TabsProps {
selectedTabIds: number[];
setSelectedTabIds: Dispatch<SetStateAction<number[]>>;
}

export default function Tabs({ selectedTabIds, setSelectedTabIds }: TabsProps) {
const [Tabs, setTabs] = useState<TabType[]>(INITIAL_TABS);

const handleSelectTab = (id: number) => {
setSelectedTabIds((prev) => {
if (prev.includes(id)) {
return prev.filter((selectedTabId) => selectedTabId !== id);
} else {
return [...prev, id];
}
});
};

useEffect(() => {
setTabs((prev) =>
prev.map((tab) => ({
...tab,
isSelected: selectedTabIds.includes(tab.id),
}))
);
}, [selectedTabIds]);

return (
<div className='mb-4 grid grid-cols-3 gap-2 p-3'>
{Tabs.map((tab) => (
<Tab
key={tab.id}
id={tab.id}
isSelected={tab.isSelected}
setSelectedTab={handleSelectTab as Dispatch<SetStateAction<number>>} // TODO: Tab 컴포넌트의 setSelectedTab prop 대신 handleSelectTab 함수를 넘겨주도록 수정
>
{tab.children}
</Tab>
))}
</div>
);
}

지금 코드를 보면 setSelectedTab prop에 handleSelectTab 함수를 넘겨주고 있다. 하지만 setSelectedTab prop은 Dispatch<SetStateAction<number>> 타입을 가지고 있기 때문에 handleSelectTab 함수를 타입 단언을 통해 setSelectedTab prop에 넘겨주고 있다.

Tab 컴포넌트에서 onClick 핸들러를 prop으로 받아서 사용하도록 하면 해결 가능하다.

// components/common/Tab.tsx
import { Dispatch, SetStateAction } from 'react';

interface TabProps {
children: React.ReactNode;
id: number;
isSelected: boolean;
onClick: (id: number) => void;
}

export default function Tab({ children, id, isSelected, onClick }: TabProps) {
function handleClick() {
onClick(id);
}

return (
<button
type='button'
className={`${
isSelected
? 'bg-bk100 text-white active:bg-bk80'
: 'border border-bk10 bg-white text-black active:bg-bk10'
} hover:bg- box-border h-8 min-w-fit rounded-full px-[0.9375rem] text-body2 transition-colors`}
onClick={handleClick}
>
{children}
</button>
);
}

바닐라 JS로 리액트 만드는 스터디 - SPA

노션에 정리해두었다.

다음 주가 벌써 마지막이다. 지금까지 구현한 걸 써먹은 간단한 프로젝트를 해오는게 다음 주차 과제다.

카공실록 회의

API 명세서도 어느정도 나왔고, 그에 맞게 작업하면 될 것 같다.

API 구현이 늦어질 것 같아 내가 팀원들에게 프론트엔드에서 MSW로 모킹해서 쓰자고 제안했다.

전 프로젝트에서 사용 경험이 있었는데 되게 편한 기억이 있어 미리 구축해두고 사용하면 좋을 것 같다.

로그인 페이지도 내가 작업하기로 했다. 그냥 UI만 구현하면 되니까 금방 할 수 있을 것 같다.

내일은 MSW 세팅하고 UI들 구현해야겠다!


내일 할 일

  • 알고리즘 문제 풀이
  • 카공실록 개발
    • MSW 세팅
    • 카공 기록 바텀시트 UI 구현
  • 부스트캠프 자소서 작성